#include "Semaforo.h"

//using namespace std;

Semaforo::Semaforo() {
}

Semaforo::Semaforo(unsigned int valor_inicial, const string nom) {
	valor = valor_inicial;
	nombre = nom;

	sem = sem_open((char*) nombre.c_str(), O_CREAT | O_EXCL, 0644, valor);
	if (sem == SEM_FAILED) {
		if (errno == EEXIST) {
			//YA HAY UNO EXISTENTE CON ESE NOMBRE, ME ATACHO A EL.
			sem = sem_open((char*) nombre.c_str(), O_EXCL, 0644, valor);
		} else {
			perror(" [ERROR] No se pudo crear el semáforo.");
			exit(1);
		}
	}
}

Semaforo::~Semaforo() {
	//LIBERO EL SEMÁFORO.
	Liberar();
}

void Semaforo::Eliminar() {
	//VALIDAR EL ERRNO, SI ES POR PERMISOS, EXTENSIÓN DEL NOMBRE O NOMBRE INVÁLIDO.
	if (sem_unlink((char*) nombre.c_str()) == -1) {
		if (errno != ENOENT)
			perror(" [ERROR] Semáforo no válido.");
	}
}

void Semaforo::P() {
	if (sem_wait(sem) == -1)
		perror(" [ERROR] Semáforo no válido.");
}

bool Semaforo::TryP() {
	if (sem_trywait(sem) != 0) {
		if (errno == EAGAIN)
			return false;
		else
			perror(" [ERROR] Error al ejecutar TryP en el semáforo.");
	}

	return true;
}

void Semaforo::V() {
	if (sem_post(sem) == -1)
		perror(" [ERROR] Semáforo no válido.");
}

string Semaforo::getNombre() {
	return this->nombre;
}

//MÉTODOS PRIVADOS.

void Semaforo::Liberar() {
	if (sem_close(sem) == -1)
		perror(" [ERROR] Semáforo no válido.");
}
